﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using StyleMVVM.DependencyInjection;
using StyleMVVM.UnitTests.TestClasses.ValidationObjects;
using StyleMVVM.Validation;

namespace StyleMVVM.UnitTests.Validation.TestRules
{
	[Export(typeof(IValidationMethodProvider<MethodSimpleTestObject>))]
	public class MethodValidationSimpleRules : IValidationMethodProvider<MethodSimpleTestObject>
	{
		public void ProvideRules(IValidationMethodCollection<MethodSimpleTestObject> methodCollection)
		{
			methodCollection.AddRule(IntTestMethod).MonitorProperty(x => x.TestInt);

			methodCollection.AddRule(NameRequiredMethod).MonitorProperty(x => x.Name);

			methodCollection.AddAsyncRule(AsyncIntTestMethod).MonitorProperty(x => x.TestInt);
		}

		private Task AsyncIntTestMethod(IRuleExecutionContext<MethodSimpleTestObject> arg)
		{
			return Task.Run(() =>
				                {
					                new ManualResetEvent(false).WaitOne(100);

					                if (arg.ValidationObject.TestInt < 1)
					                {
						                arg.AddRequired("TestInt", "TestInt is required");
					                }
				                });
		}

		private void IntTestMethod(IRuleExecutionContext<MethodSimpleTestObject> obj)
		{
			if (obj.ValidationObject.TestInt < 1 || obj.ValidationObject.TestInt > 4)
			{
				obj.AddError("TestInt", "TestInt must be between 1 and 4");
			}
		}

		private void NameRequiredMethod(IRuleExecutionContext<MethodSimpleTestObject> obj)
		{
			if (string.IsNullOrEmpty(obj.ValidationObject.Name))
			{
				obj.AddRequired("Name", "Name is required");
			}
		}
	}
}